package com.ysqcould.mp.service.impl;

import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

import cn.hutool.core.util.ObjectUtil;
import com.ysqcould.allocation.utils.UploadFileUtil;
import com.ysqcould.common.core.domain.AjaxResult;
import com.ysqcould.common.enums.QrCodeStatus;
import com.ysqcould.common.utils.DateUtils;
import com.ysqcould.mp.domain.vo.WxResultBody;
import com.ysqcould.mp.utils.HttpUtils;
import com.ysqcould.mp.utils.MyCookieStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ysqcould.mp.mapper.MpTokenMapper;
import com.ysqcould.mp.domain.MpToken;
import com.ysqcould.mp.service.IMpTokenService;

import static com.ysqcould.mp.task.CollectTask.CollectTask;
import static com.ysqcould.mp.utils.QrCodeUtil.*;
import static com.ysqcould.mp.utils.QrCodeUtil.getQRCode;

/**
 * 登录TOKENService业务层处理
 * 
 * @author ruoyi
 * @date 2022-10-18
 */
@Service
public class MpTokenServiceImpl implements IMpTokenService 
{
    @Autowired
    private MpTokenMapper mpTokenMapper;



    /**
     * 查询登录TOKEN
     * 
     * @param id 登录TOKEN主键
     * @return 登录TOKEN
     */
    @Override
    public MpToken selectMpTokenById(Long id)
    {
        return mpTokenMapper.selectMpTokenById(id);
    }

    /**
     * 查询登录TOKEN列表
     * 
     * @param mpToken 登录TOKEN
     * @return 登录TOKEN
     */
    @Override
    public List<MpToken> selectMpTokenList(MpToken mpToken)
    {
        return mpTokenMapper.selectMpTokenList(mpToken);
    }

    /**
     * 新增登录TOKEN
     * 
     * @param mpToken 登录TOKEN
     * @return 结果
     */
    @Override
    public int insertMpToken(MpToken mpToken)
    {
        mpToken.setCreateTime(DateUtils.getNowDate());
        return mpTokenMapper.insertMpToken(mpToken);
    }

    /**
     * 修改登录TOKEN
     * 
     * @param mpToken 登录TOKEN
     * @return 结果
     */
    @Override
    public int updateMpToken(MpToken mpToken)
    {
        mpToken.setUpdateTime(DateUtils.getNowDate());
        return mpTokenMapper.updateMpToken(mpToken);
    }

    /**
     * 批量删除登录TOKEN
     * 
     * @param ids 需要删除的登录TOKEN主键
     * @return 结果
     */
    @Override
    public int deleteMpTokenByIds(Long[] ids)
    {
        return mpTokenMapper.deleteMpTokenByIds(ids);
    }

    /**
     * 删除登录TOKEN信息
     * 
     * @param id 登录TOKEN主键
     * @return 结果
     */
    @Override
    public int deleteMpTokenById(Long id)
    {
        return mpTokenMapper.deleteMpTokenById(id);
    }

    @Override
    public MpToken selectQrcode() {

        return mpTokenMapper.selectQrcode();
    }

    @Override
    public AjaxResult getQrCode() {
        String sessionId=""+System.currentTimeMillis() + (int)(Math.random()*100);
        /**
         * 开启请求接口
         */
        WxResultBody wxResultBody = startLogin(sessionId);
        System.out.println("---开始请求接口，返回结果"+wxResultBody.toString());
        /**
         * 获取图片输出流
         */
        MpToken mpToken = saveQrcode(sessionId);
        FutureTask<Integer> futureTask=new FutureTask<>(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                while (true) {
                    WxResultBody askQRCode =askQRCode();
                    Integer status = askQRCode.getStatus();
                    if (status == QrCodeStatus.EXPIRED.getStatus()) {
                        System.out.println("二维码已过期");
                        return QrCodeStatus.EXPIRED.getStatus();
                    } else if (status == QrCodeStatus.SCANNED.getStatus()) {
                        System.out.println("已扫码，等待确认");
                    } else if (status == QrCodeStatus.CONFIRMED.getStatus()) {
                        System.out.println("已确认登录，请稍后...");
                        return QrCodeStatus.CONFIRMED.getStatus();
                    }
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

        while (true) {
            Thread queryThread = new Thread(futureTask);
            queryThread.start();
            if (!futureTask.isDone()) {
                System.out.println("--正在查询扫码状态，请尽快扫码！");
            }

            try {
                Integer integer = futureTask.get();
                String status = QrCodeStatus.SCANNED.getName();;
                if (integer == QrCodeStatus.CONFIRMED.getStatus()) {
                    //说明扫码确认成功，否则重新获取图片
                    System.out.println("扫码确认成功");
                    status = QrCodeStatus.CONFIRMED.getName();
                    mpToken.setStatus(status);
                    mpToken.setUpdateTime(DateUtils.getNowDate());
                    mpTokenMapper.updateMpToken(mpToken);
                    break;
                } else {
                    if (integer == QrCodeStatus.EXPIRED.getStatus()) {
                        status = QrCodeStatus.EXPIRED.getName();
                    }
                    mpToken.setStatus(status);
                    mpToken.setUpdateTime(DateUtils.getNowDate());
                    mpTokenMapper.updateMpToken(mpToken);
                    // 重新获取二维码图片
                    mpToken = saveQrcode(sessionId);
                }
            } catch (Exception e) {
                System.out.println("查询接口出错了");
                break;
            }
        }
        // 4.确认登录后，请求登录接口，拿到登录状态的cookie
        WxResultBody bizlogin = bizlogin();
        //重定向地址
        String redirect_url = bizlogin.getRedirect_url();
        //解析成键值对
        Map<String, String> loginRes = HttpUtils.parseQueryParams(redirect_url);
        System.out.println("loginRes");
        System.out.println(loginRes);
        //得到token
        String token = loginRes.get("token");
        //设置全局token值
        MyCookieStore.setToken(token);

        // token 保存数据库
        mpToken.setStatus(QrCodeStatus.SUCCESS.getName());
        mpToken.setToken(token);
        mpToken.setUpdateTime(DateUtils.getNowDate());
        mpTokenMapper.updateMpToken(mpToken);
        System.out.println("---恭喜你，登录成功！");
        /**
         * 扫码登录后开始采集文章数据
         */
        CollectTask();
        return AjaxResult.success(mpToken.getQrCode());
    }

    @Override
    public MpToken selectMpToken() {
        return mpTokenMapper.getToken();
    }

    /**
     * 返回二维码地址
     * @param sessionId
     * @return
     */
    private MpToken  saveQrcode(String sessionId) {
        //先删除数据库中的二维码图片
        MpToken t=new MpToken();
        MpToken mpToken = mpTokenMapper.selectQrcode();
        if (ObjectUtil.isNotEmpty(mpToken)){
            mpTokenMapper.deleteMpTokenById(mpToken.getId());
            InputStream qrCodeIs = getQRCode();
            String  fileName=sessionId+".jpg";
            String s = UploadFileUtil.AliOSSUpload(qrCodeIs, fileName);
            t.setToken(null);
            t.setQrCode(s);
            t.setStatus(QrCodeStatus.UNSCAN.getName());
            t.setCreateTime(DateUtils.getNowDate());
            t.setUpdateTime(DateUtils.getNowDate());
            mpTokenMapper.insertMpToken(t);
        }else {
            InputStream qrCodeIs = getQRCode();
            String  fileName=sessionId+".jpg";
            String s = UploadFileUtil.AliOSSUpload(qrCodeIs, fileName);
            t.setToken(null);
            t.setQrCode(s);
            t.setStatus(QrCodeStatus.UNSCAN.getName());
            t.setCreateTime(DateUtils.getNowDate());
            t.setUpdateTime(DateUtils.getNowDate());
            mpTokenMapper.insertMpToken(t);
        }
        return t;
    }

}
